Skip to content

feat(renderer3d): add linear fog mode with start/end distance controls - #665

Merged
aram-devdocs merged 10 commits into
mainfrom
codex/issue-631-linear-fog-mode
Apr 3, 2026
Merged

feat(renderer3d): add linear fog mode with start/end distance controls#665
aram-devdocs merged 10 commits into
mainfrom
codex/issue-631-linear-fog-mode

Conversation

@aram-devdocs

Copy link
Copy Markdown
Owner

Overview

Type: feature

Summary:
Adds a linear fog mode with explicit start/end distance parameters to the 3D renderer. The existing exponential fog (ConfigureFog) remains backward compatible. Linear fog allows precise control over where fog begins and ends, which is critical for games with varying camera distances.

Related Issues: Closes #631


Changes Made

Engine Core (goud_engine/src/)

  • Added FogMode enum (Exponential { density } | Linear { start, end }) in renderer3d/types.rs
  • Replaced density: f32 field in FogConfig with mode: FogMode
  • Added helper methods (mode_int(), density(), start(), end()) for shader uniform upload
  • Updated all OpenGL (GLSL) and WGSL shaders with linear fog branch and division-by-zero guard
  • Added fog_mode, fog_start, fog_end uniform locations to MainUniforms and GridUniforms

FFI Layer (goud_engine/src/ffi/)

  • Added goud_renderer3d_configure_fog_linear(context_id, enabled, start_distance, end_distance, r, g, b) FFI function
  • Updated existing goud_renderer3d_configure_fog to use FogMode::Exponential internally

C# SDK (sdks/csharp/)

  • Generated ConfigureFogLinear method in GoudGame.g.cs and NativeMethods.g.cs

Python SDK (sdks/python/)

  • Generated configure_fog_linear in _game.py and _ffi.py

TypeScript SDK (sdks/typescript/)

  • Node napi binding changes
  • Web WASM binding changes
  • Type definition changes
  • Tests updated

Codegen Pipeline (codegen/)

  • Schema changes (configureFogLinear method added)
  • Generator changes
  • Validator changes
  • ffi_mapping changes (goud_renderer3d_configure_fog_linear mapped)

Proc Macros (goud_engine_macros/)

  • #[goud_api] attribute changes
    No changes

Tools (tools/)

  • lint-layers changes
    No changes

WASM (goud_engine/src/wasm/)

  • wasm-bindgen exports
  • Sprite renderer changes
  • Texture loader changes
    No changes

Examples (examples/)

No changes

Documentation

No changes


Architectural Compliance

  • Rust-first: All logic lives in Rust; SDKs are thin wrappers
  • FFI boundary: New exports use #[no_mangle] extern "C" and #[repr(C)] where needed
  • Dependency flow: Imports follow layer hierarchy (down only)
  • SDK parity: Changes exposed via FFI are wrapped in C#, Python, AND TypeScript SDKs
  • Unsafe discipline: No unsafe block without a // SAFETY: comment
  • File size: No file exceeds 500 lines

Testing

  • cargo test passes (4873 passed, 0 failed, 26 ignored GPU-context tests)
  • cargo clippy -- -D warnings is clean
  • cargo fmt --all -- --check passes
  • Python SDK tests pass (python3 sdks/python/test_bindings.py) — if SDK changed
  • C# SDK tests pass (dotnet test sdks/csharp.tests/) — if SDK changed
  • TypeScript SDK tests pass (cd sdks/typescript && npm test) — if TS SDK changed
  • Codegen produces consistent output (python3 codegen/validate.py && python3 codegen/validate_coverage.py)
  • Pre-commit hooks pass

Code Quality

  • No todo!() or unimplemented!() in production code
  • No #[allow(unused)] without justification comment
  • Error handling uses Result, not unwrap()/expect() in library code
  • Public items have doc comments

Documentation

  • Updated relevant AGENTS.md files (if architecture changed)
  • Updated README.md (if user-facing behavior changed)
  • Added or updated doc comments on new public APIs

Breaking Changes

None

  • API changes: None (additive only — new ConfigureFogLinear function)
  • FFI signature changes: None (existing configure_fog unchanged)
  • SDK interface changes: None (additive only)

Version Bump

Bump type: minor
Justification: New public API surface (ConfigureFogLinear)


Security

  • No new unsafe blocks — or each one has a // SAFETY: comment and is necessary
  • No new FFI pointer parameters without null checks
  • No new dependencies with known advisories (cargo deny check)
  • No secrets or credentials in committed files

Performance

Linear fog adds one shader branch per fragment when fog is enabled. The branch is uniform-driven (same for all fragments in a draw call), so GPU branch prediction handles it efficiently. No allocation changes.


Deployment

  • NuGet package version updated (if SDK changed)
  • Python package version updated (if SDK changed)
  • npm package version updated (if TS SDK changed)
  • Native library builds on all targets (macOS, Linux, Windows)

Reviewer Notes

  • The WGSL uniform struct layout was extended with 3 new fields (fogMode, fogStart, fogEnd) plus padding. All 8 WGSL struct copies were updated consistently.
  • Division-by-zero guard (max(end - start, 0.00001)) prevents undefined behavior when start == end.
  • The existing OpenGL grid shader uses simple exp(-d*dist) while main shaders use exp(-(d*dist)^2) — this pre-existing inconsistency was preserved.

aram-devdocs and others added 2 commits April 3, 2026 09:36
Adds FogMode enum (Exponential/Linear) to FogConfig, a new
goud_renderer3d_configure_fog_linear FFI function, and linear fog
branch in all OpenGL and WGSL shaders. Existing ConfigureFog API
remains backward compatible.

Closes #631

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add FogConfig unit tests (mode_int, density, start, end, default)
- Add FFI invalid-context test for configure_fog_linear
- Add SDK headless test for configure_fog_linear
- Guard linear fog shader denominator with max(..., 0.00001)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the size/L label Apr 3, 2026
@claude

claude Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Claude finished @aram-devdocs's task in 1m 53s —— View job


PR Review: feat(renderer3d): add linear fog mode with start/end distance controls

Tasks

  • Context gathering (CLAUDE.md, PR metadata)
  • Phase 1: Context & layer identification
  • Phase 2: Architecture validation
  • Phase 3: Anti-pattern scan
  • Phase 4: Quality assessment
  • Phase 5: Security review (FFI/unsafe)
  • Phase 6: Scope verification
  • Phase 7: Final verdict

Verdict: CHANGES REQUESTED

One blocker must be addressed before merge. Warnings are non-blocking but recommended.


BLOCKERS

# File Issue
1 goud_engine/src/jni/generated.rs, sdks/kotlin/src/main/kotlin/com/goudengine/core/GoudGame.kt, sdks/kotlin/src/main/java/…/GoudGameNative.java Unrelated Kotlin/JNI regression: Four gamepad JNI functions were silently removed (isGamepadButtonPressed, isGamepadButtonJustPressed, isGamepadButtonJustReleased, getGamepadAxis) along with their Kotlin wrappers. The PR description claims "No changes" to JNI/Kotlin. This is a hidden scope change that breaks the Kotlin SDK's gamepad API. Either revert these deletions, or open a separate PR with a clear explanation. Fix this →

WARNINGS

# File Issue
1 goud_engine/src/ffi/renderer3d/environment/mod.rs:205 Parameter ordering inconsistency: configure_fog(ctx, enabled, r, g, b, density) puts color before mode-params, but configure_fog_linear(ctx, enabled, start, end, r, g, b) puts color after mode-params. A caller switching between the two APIs will trip on this mismatch. Consider (ctx, enabled, r, g, b, start, end) for consistency.
2 goud_engine/src/libs/graphics/renderer3d/types.rs:384 Missing start > end validation doc comment: When start_distance > end_distance, max(fogEnd - fogStart, 0.00001) clamps the denominator to the epsilon value, producing wildly incorrect results for all visible distances. The function won't panic, but the visual output will be confusing. A doc comment explaining the expected invariant (start < end) and behavior if violated would save future debuggers.
3 goud_engine/src/libs/graphics/renderer3d/shader_sources.in:400-415 Grid shader uses exp(-d * dist) while main shaders use exp(-(d*dist)²): This is a pre-existing inconsistency acknowledged in the reviewer notes. Keeping it as-is is defensible, but users enabling linear fog will get slightly different falloff on grid lines vs objects at the same distance.

Positive Callouts

  • FogMode enum design is clean: Named struct variants (Exponential { density }, Linear { start, end }) are idiomatic and self-documenting. The helper methods (mode_int(), density(), start(), end()) correctly isolate the shader-upload concern.
  • Division-by-zero guard: max(fogEnd - fogStart, 0.00001) is the right pattern in both GLSL and WGSL shaders. No undefined behavior even when start == end.
  • Test coverage: Unit tests for all four FogConfig helper methods plus a headless SDK test and an invalid-context FFI test — solid baseline coverage.
  • SDK parity: All six language SDKs (C#, Python, TypeScript, Go, Swift, Kotlin — ignoring the regression) received the new binding. Schema and FFI manifest updated consistently.
  • Backward compatibility: Existing configure_fog continues to produce FogMode::Exponential unchanged. Zero breaking changes.
  • WGSL struct padding: _padFog: f32 correctly maintains 16-byte alignment before the lights array.

Summary

The fog implementation itself is clean and correct. The only thing blocking merge is the accidental removal of gamepad bindings from the Kotlin/JNI layer — these appear to have been pulled in from an unrelated branch or merge. The parameter-order inconsistency is worth addressing but non-blocking.

- Extract FogConfig tests into types_tests.rs (types.rs 591->499)
- Condense comments in render_helpers.rs (505->499)
- Condense module docs in rendering_3d.rs (503->496)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/L and removed size/L labels Apr 3, 2026
The web WASM target has manually listed stub methods in gen_ts_web.py.
The new configureFogLinear method was missing, causing the TS web build
to fail with TS2420 (class doesn't implement interface).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/L and removed size/L labels Apr 3, 2026
The JNI/Kotlin codegen was missing 4 gamepad button/axis functions
because they weren't registered in the schema or ffi_mapping.
Also adds gamepad.rs to the build manifest FFI source list and
adds .worktrees/ to .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/L labels Apr 3, 2026
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
The 15min timeout is too short on cold cache runs, causing consistent
cancellation failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
Restores typed enum parameters for gamepad methods matching the
existing Android example expectations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
Removes unused pre-installed software (dotnet, Android SDK, GHC,
CodeQL) and Docker images to prevent "No space left on device"
during the static archive step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
@aram-devdocs
aram-devdocs merged commit a0a7b49 into main Apr 3, 2026
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add linear fog mode with start/end distance controls

1 participant